/*
 * PacketFile.cpp
 *
 *  Created on: 2016年10月9日
 *      Author: zhengboyuan
 */

#include "PacketFile.h"
#include <algorithm>
#include <fstream>
#include <functional>
#include <string.h>

namespace av
{



PacketIndexFile::PacketIndexFile():
		m_filename()
{

}

PacketIndexFile::~PacketIndexFile()
{
	close();
}

bool PacketIndexFile::open(const char* filename)
{
	close();

	m_ifs.open(filename, std::ios::binary|std::ios::in);
	if (!m_ifs.is_open())
	{
		return false;
	}

	m_indexArray.clear();

	while (!m_ifs.eof())
	{
		PacketIndex entry;
		memset(&entry, 0, sizeof(entry));

		if (!m_ifs.read((char*)&entry, sizeof(entry)).good())
		{
			break;
		}

		m_indexArray.push_back(entry);
	}

	return true;
}

void PacketIndexFile::close()
{
	m_ifs.close();
}

bool PacketIndexFile::isOpen()
{
	return m_ifs.is_open();
}

bool PacketIndexFile::reload()
{
	m_ifs.clear();

	std::streampos pos = m_ifs.tellg();
	m_ifs.seekg(0, std::ios_base::beg);
	std::streampos fileSize = m_ifs.tellg();
	if (fileSize != pos)
	{
		int a = 0;
		a++;
	}

	std::streamsize size = sizeof(PacketIndex) * m_indexArray.size();
	m_ifs.seekg(size, std::ios_base::beg);

	int count = 0;
	while (!m_ifs.eof())
	{
		PacketIndex entry;
		memset(&entry, 0, sizeof(entry));

		if (!m_ifs.read((char*)&entry, sizeof(entry)).good())
		{
			break;
		}

		m_indexArray.push_back(entry);
		count ++;
	}

	return (count > 0);
}

int64_t PacketIndexFile::getDuration()
{
	if (m_indexArray.empty())
	{
		return 0;
	}

	if (m_indexArray.size() <= 1)
	{
		return 0;
	}

	PacketIndex& front = m_indexArray.front();
	PacketIndex& back = m_indexArray.back();

	return back.timestamp - front.timestamp;
}

int64_t PacketIndexFile::getStartTime()
{
	int64_t tm = 0;
	if (m_indexArray.size() > 0)
	{
		tm = m_indexArray.front().timestamp;
	}
	return tm;
}



struct IndexComparator : public std::binary_function<PacketIndex, PacketIndex, bool>
{
	bool operator () (const PacketIndex& first, const PacketIndex& second) const
	{
		return first.timestamp < second.timestamp;
	}
};


bool PacketIndexFile::locate(int64_t offset, PacketIndex& entry)
{
	if (m_indexArray.empty())
	{
		return false;
	}

	if (m_indexArray.size() <= 1)
	{
		entry = m_indexArray.front();
		return true;
	}

	PacketIndex& front = m_indexArray.front();
	int64_t time = m_indexArray.front().timestamp + offset;

	PacketIndex target;
	memset(&target, 0, sizeof(target));
	target.timestamp = time;

	bool found = false;
	PacketIndexArray::iterator it = std::lower_bound(m_indexArray.begin(), m_indexArray.end(), target, IndexComparator());
	if (it != m_indexArray.end())
	{
		entry = *it;
		found = true;
	}
	return found;
}





PacketFile::PacketFile()
{

}

PacketFile::~PacketFile()
{
}




} /* namespace av */
